#include "stdafx.h"
#include "MaterialManager.h"

CMaterialManager gMaterialManager;

CMaterialManager::CMaterialManager(void)
{
}

CMaterialManager::~CMaterialManager(void)
{
	std::list<SMaterial*>::iterator it = m_Materials.begin();
	for (; it != m_Materials.end(); ++it)
	{
		delete (*it);
	}
}


SMaterial* CMaterialManager::FindMaterial(float &r, float &g, float &b, float &a)
{
	std::list<SMaterial*>::iterator it = m_Materials.begin();
	for (; it != m_Materials.end(); ++it)
	{
		if ((*it)->texture == NULL &&
			r == (*it)->diffuse[0] && g == (*it)->diffuse[1] && 
			b == (*it)->diffuse[2] && a == (*it)->diffuse[3])
			return (*it);
	}
	return NULL;
}

SMaterial* CMaterialManager::FindMaterial(CTexture *texture)
{
	std::list<SMaterial*>::iterator it = m_Materials.begin();
	for (; it != m_Materials.end(); ++it)
	{
		if (texture == (*it)->texture)
			return (*it);
	}
	return NULL;
}

SMaterial* CMaterialManager::FindMaterial(float *amb, float *dif, float *emi, float *spe)
{
	std::list<SMaterial*>::iterator it = m_Materials.begin();
	for (; it != m_Materials.end(); ++it)
	{
		if ((*it)->texture == NULL &&
			amb[0] == (*it)->ambient[0] && amb[1] == (*it)->ambient[1] && 
			amb[2] == (*it)->ambient[2] && amb[3] == (*it)->ambient[3] &&
			dif[0] == (*it)->diffuse[0] && dif[1] == (*it)->diffuse[1] && 
			dif[2] == (*it)->diffuse[2] && dif[3] == (*it)->diffuse[3] &&
			emi[0] == (*it)->emissive[0] && emi[1] == (*it)->emissive[1] && 
			emi[2] == (*it)->emissive[2] && emi[3] == (*it)->emissive[3] &&
			spe[0] == (*it)->specular[0] && spe[1] == (*it)->specular[1] && 
			spe[2] == (*it)->specular[2] && spe[3] == (*it)->specular[3])
			return (*it);
	}
	return NULL;
}

SMaterial*  CMaterialManager::AddMaterial(float &r, float &g, float &b, float &a)
{
	SMaterial *mtrl = FindMaterial(r, g, b, a);
	if (mtrl == NULL)
	{
		mtrl = new SMaterial;
		mtrl->diffuse[0] = r / 255.0;
		mtrl->diffuse[1] = g / 255.0;
		mtrl->diffuse[2] = b / 255.0;
		mtrl->diffuse[3] = a / 255.0;

		mtrl->ambient[0] = mtrl->diffuse[0];
		mtrl->ambient[1] = mtrl->diffuse[1];
		mtrl->ambient[2] = mtrl->diffuse[2];
		mtrl->ambient[3] = mtrl->diffuse[3];
		mtrl->emissive[0] = 0.0;
		mtrl->emissive[1] = 0.0;
		mtrl->emissive[2] = 0.0;
		mtrl->emissive[3] = mtrl->diffuse[3];
		mtrl->specular[0] = (mtrl->diffuse[0] + mtrl->diffuse[1] + mtrl->diffuse[2]) * 0.03;
		mtrl->specular[1] = mtrl->specular[0];
		mtrl->specular[2] = mtrl->specular[0];
		mtrl->specular[3] = mtrl->diffuse[3];
		mtrl->shininess = 0.3;
		mtrl->texture = NULL;

		m_Materials.push_back(mtrl);
	}
	return mtrl;
}


SMaterial*  CMaterialManager::AddMaterial(CTexture *texture)
{
	SMaterial *mtrl = FindMaterial(texture);
	if (mtrl == NULL)
	{
		mtrl = new SMaterial;
		mtrl->diffuse[0] = 1.0;
		mtrl->diffuse[1] = 1.0;
		mtrl->diffuse[2] = 1.0;
		mtrl->diffuse[3] = 1.0;
		mtrl->ambient[0] = 1.0;
		mtrl->ambient[1] = 1.0;
		mtrl->ambient[2] = 1.0;
		mtrl->ambient[3] = 1.0;
		mtrl->emissive[0] = 0.0;
		mtrl->emissive[1] = 0.0;
		mtrl->emissive[2] = 0.0;
		mtrl->emissive[3] = 1.0;
		mtrl->specular[0] = 0.1;
		mtrl->specular[1] = 0.1;
		mtrl->specular[2] = 0.1;
		mtrl->specular[3] = 1.0;
		mtrl->shininess = 0.3;
		mtrl->texture = texture;

		m_Materials.push_back(mtrl);
	}
	return mtrl;
}


SMaterial*  CMaterialManager::AddMaterial(float *amb, float *dif, float *emi, float *spe)
{
	SMaterial *mtrl = FindMaterial(amb, dif, emi, spe);
	if (mtrl == NULL)
	{
		mtrl = new SMaterial;
		for (int i = 0; i < 4; i++)
		{
			mtrl->diffuse[i] = dif[i];
			mtrl->ambient[i] = amb[i];
			mtrl->emissive[i] = emi[i];
			mtrl->specular[i] = spe[i];
		}
		mtrl->shininess = 0.3;
		mtrl->texture = NULL;
		m_Materials.push_back(mtrl);
	}
	return mtrl;
}
